﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PCR.Logic
{
    using PCR.Base;

    /// <summary>
    /// Configuration xml database
    /// </summary>
    public class XmlConfig : IConfigAccess
    {
        protected System.Xml.XmlDocument _doc;
        protected string _filename;
        IPrintingSetting _defaultSetting;

        /// <summary>
        /// Xml tag definition
        /// </summary>
        static readonly string PrintingSetting_Tag = "PrintingSetting";
        static readonly string PrintingTitle_Tag = "Title";
        static readonly string PrintingProjectName_Tag = "ProjectName";
        static readonly string PrintingNote_Tag = "Note";
        static readonly string PrintingQuestion_Tag = "Question";
        static readonly string PrintingMedicalBranch_Tag = "MedicalBranch";
        static readonly string PrintingBedNo_Tag = "BedNo";
        static readonly string PrintingSenderDoctor_Tag = "SenderDoctor";
        static readonly string PrintingDiagnosis_Tag = "Diagnosis";
        static readonly string PrintingMemo_Tag = "Memo";
        static readonly string PrintingCheckerSignature_Tag = "CheckerSignature";
        static readonly string PrintingAuditorSignature_Tag = "AuditorSignature";
        
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="doc">xml doccument</param>
        /// <param name="filename">xml filename, used to store data to the file</param>
        public XmlConfig(System.Xml.XmlDocument doc,
            string filename)
        {
            System.Diagnostics.Debug.Assert(doc != null);
            System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(filename));
            
            this._doc = doc;
            this._filename = filename;
            this._defaultSetting = new PrintingSetting();

            this._defaultSetting.Title = "中国医科大学附属盛京医院检验报告单";
            this._defaultSetting.ProjectName = "人乳头瘤病毒（HPV）15种高危亚型分型定量";
            this._defaultSetting.Note = "1、高危型HPV与宫颈癌的关系，就像乙型肝炎病毒与肝癌、吸烟与肺癌的关系一样，不必惊恐，但要重视。\r\n2、感染高危亚型HPV患者，如无宫颈上皮内病变，请定期复查，间隔不低于6个月（HPV自然消退期为8~10个月）。\r\n3、感染单位定义：相当于单位细胞数的病毒感染量。";
            this._defaultSetting.Question = "此结果仅对次标本负责，此标本保存48小时，如有疑问请及时查询";
        }
        
        public IPrintingSetting PrintingSetting 
        {
            get { return LoadPrintingSetting(); }
            set { SavePrintingSetting(value); }
        }
        
        protected IPrintingSetting LoadPrintingSetting()
        {
            IPrintingSetting printingSetting = new PrintingSetting();

            FillPrintingSettingWithNode(printingSetting, GetPrintingSettingNode());

            return printingSetting;
        }

        protected void SavePrintingSetting(IPrintingSetting printingSetting)
        {
            FillNodeWithPrintingSetting(GetPrintingSettingNode(), printingSetting);
            Save();
        }

        protected System.Xml.XmlNode GetPrintingSettingNode()
        {
            System.Xml.XmlNode nodeRoot = this._doc.SelectSingleNode("PCRConfig");
            System.Diagnostics.Debug.Assert(nodeRoot != null, "PCRConfig xml tag can not be empty!");
            System.Xml.XmlNode nodePrintingSetting = nodeRoot.SelectSingleNode(PrintingSetting_Tag);
            if (nodePrintingSetting == null) // Add the node if not existed
            {
                nodePrintingSetting = this._doc.CreateElement(PrintingSetting_Tag);
                FillNodeWithPrintingSetting(nodePrintingSetting, GetDefaultPrintingSetting());
                nodeRoot.AppendChild(nodePrintingSetting);
                Save();
            }

            return nodePrintingSetting;
        }

        IPrintingSetting GetDefaultPrintingSetting()
        {
            IPrintingSetting defaultSetting = new PrintingSetting();

            defaultSetting.Title = "中国医科大学附属盛京医院检验报告单";
            defaultSetting.ProjectName = "人乳头瘤病毒（HPV）15种高危亚型分型定量";
            defaultSetting.Note = "1、高危型HPV与宫颈癌的关系，就像乙型肝炎病毒与肝癌、吸烟与肺癌的关系一样，不必惊恐，但要重视。\r\n2、感染高危亚型HPV患者，如无宫颈上皮内病变，请定期复查，间隔不低于6个月（HPV自然消退期为8~10个月）。\r\n3、感染单位定义：相当于单位细胞数的病毒感染量。";
            defaultSetting.Question = "此结果仅对次标本负责，此标本保存48小时，如有疑问请及时查询";

            return defaultSetting;
        }

        void FillNodeWithPrintingSetting(System.Xml.XmlNode node,
            IPrintingSetting printingSetting)
        {
            System.Diagnostics.Debug.Assert(node != null);
            System.Diagnostics.Debug.Assert(printingSetting != null);

            // Get <Title> attribute
            System.Xml.XmlAttribute attr = this._doc.CreateAttribute(PrintingTitle_Tag);
            attr.Value = printingSetting.Title;
            node.Attributes.Append(attr);

            // Get <ProjectName> attribute
            attr = this._doc.CreateAttribute(PrintingProjectName_Tag);
            attr.Value = printingSetting.ProjectName;
            node.Attributes.Append(attr);

            // Get <Note> attribute
            attr = this._doc.CreateAttribute(PrintingNote_Tag);
            attr.Value = printingSetting.Note;
            node.Attributes.Append(attr);

            // Get <Question> attribute
            attr = this._doc.CreateAttribute(PrintingQuestion_Tag);
            attr.Value = printingSetting.Question;
            node.Attributes.Append(attr);

            // Get <MedicalBranch> attribute
            attr = this._doc.CreateAttribute(PrintingMedicalBranch_Tag);
            attr.Value = printingSetting.MedicalBranch;
            node.Attributes.Append(attr);

            // Get <BedNo> attribute
            attr = this._doc.CreateAttribute(PrintingBedNo_Tag);
            attr.Value = printingSetting.BedNo;
            node.Attributes.Append(attr);

            // Get <SenderDoctor> attribute
            attr = this._doc.CreateAttribute(PrintingSenderDoctor_Tag);
            attr.Value = printingSetting.SenderDoctor;
            node.Attributes.Append(attr);
            
            // Get <Diagnosis> attribute
            attr = this._doc.CreateAttribute(PrintingDiagnosis_Tag);
            attr.Value = printingSetting.Diagnosis;
            node.Attributes.Append(attr);
            
            // Get <Memo> attribute
            attr = this._doc.CreateAttribute(PrintingMemo_Tag);
            attr.Value = printingSetting.Memo;
            node.Attributes.Append(attr);
            
            // Get <CheckerSignature> attribute
            attr = this._doc.CreateAttribute(PrintingCheckerSignature_Tag);
            attr.Value = printingSetting.CheckerSignature;
            node.Attributes.Append(attr);
            
            // Get <AuditorSignature> attribute
            attr = this._doc.CreateAttribute(PrintingAuditorSignature_Tag);
            attr.Value = printingSetting.AuditorSignature;
            node.Attributes.Append(attr);
        }

        void FillPrintingSettingWithNode(IPrintingSetting printingSetting,
            System.Xml.XmlNode node)
        {
            System.Diagnostics.Debug.Assert(node != null);
            System.Diagnostics.Debug.Assert(printingSetting != null);

            // Get <Title> attribute
            System.Xml.XmlAttribute attr = node.Attributes[PrintingTitle_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.Title = attr.Value;

            // Get <ProjectName> attribute
            attr = node.Attributes[PrintingProjectName_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.ProjectName = attr.Value;

            // Get <Note> attribute
            attr = node.Attributes[PrintingNote_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.Note = attr.Value;

            // Get <Question> attribute
            attr = node.Attributes[PrintingQuestion_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.Question = attr.Value;

            // Get <MedicalBranch> attribute
            attr = node.Attributes[PrintingMedicalBranch_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.MedicalBranch = attr.Value;
            
            // Get <BedNo> attribute
            attr = node.Attributes[PrintingBedNo_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.BedNo = attr.Value;

            // Get <SenderDoctor> attribute
            attr = node.Attributes[PrintingSenderDoctor_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.SenderDoctor = attr.Value;

            // Get <Diagnosis> attribute
            attr = node.Attributes[PrintingDiagnosis_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.Diagnosis = attr.Value;
            
            // Get <Memo> attribute
            attr = node.Attributes[PrintingMemo_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.Memo = attr.Value;

            // Get <CheckerSignature> attribute
            attr = node.Attributes[PrintingCheckerSignature_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.CheckerSignature = attr.Value;

            // Get <AuditorSignature> attribute
            attr = node.Attributes[PrintingAuditorSignature_Tag];
            System.Diagnostics.Debug.Assert(attr != null);
            printingSetting.AuditorSignature = attr.Value;
        }

        void Save()
        {
            this._doc.Save(this._filename);
        }
    }
}
